package actions;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.StringTokenizer;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JOptionPane;

import utils.Constants;
import utils.MessageViewer;
import client.ClientSocketConnection;
import client_gui.ClientWindow;
import client_gui.FindUserDialog;


/**
 * Klasa koja predstavlja akciju Find dugmeta u FindUser dialogu.
 * Ova klasa je izdvojena od ostalio Action klasa (nasledjuje JButton), jer
 * se objekat ove klase dodaje direktno u JPanel, a ne u JToolBar ili JMenu.
 * 
 * @author UrosKrkic & Radivoje Popovic
 */
public class FindAction extends JButton implements ActionListener, Constants {

	
	/**
	 * Vlasnik akcije.
	 */
	private ClientWindow owner;
	
	
	/**
	 * Glavni prozor aplikacije.
	 */
	private FindUserDialog parent;
	

	/**
	 * Konstruktor.
	 * @param owner - vlasnik akcije
	 * @param label - naziv dugmeta
	 * @author UrosKrkic & Radivoje Popovic
	 */
	public FindAction(ClientWindow owner, FindUserDialog parent) {
		super();
		this.setToolTipText("Search");
		
		this.owner = owner;
		this.parent = parent;
		
		this.addActionListener(this);
	}
	

	
	/**
	 * Metod koji setuje vlasnika ove akcije. Za razliku od klasa akcija, koje
	 * prosiruju RLMAbstarctAction, u LogginAction klasi moguce je pristupiti vlasniku
	 * akcije direktno. Metod je uveden samo zbog ocuvanja doslednosti u interfejsu za
	 * rukovanje akcijama
	 * @param owner - vlasnik aplikacije
	 * @author UrosKrkic & Radivoje Popovic
	 */
	public void setActionOwner(ClientWindow owner) {
		this.owner = owner;
	}
	
	
	
	/**
	 * Metod koji vraca referencu na vlasnika ove akcije. Za razliku od klasa akcija, koje
	 * prosiruju RLMAbstarctAction, u LogginAction klasi moguce je pristupiti vlasniku
	 * akcije direktno. Metod je uvede samo zbog ocuvanja doslednosti u interfejsu za
	 * rukovanje akcijama
	 * @author UrosKrkic & Radivoje Popovic
	 */
	public ClientWindow getActionOwner() {
		return this.owner;
	}

	
	public void actionPerformed(ActionEvent e) {
		
		if (parent.getFindParameter().length() == 0) {
			JOptionPane.showMessageDialog(parent, "You must enter keyword or *", "Find Warning", JOptionPane.WARNING_MESSAGE);
			return;
		}
		
		
		ClientSocketConnection connection = owner.getApplicaton().retrieveSocketConnection();
		
		
		StringBuffer buffer = new StringBuffer();
		buffer.append("FIND ");
		buffer.append(owner.getApplicaton().getClientUser().getUsername());
		buffer.append(" ");
		buffer.append(parent.getFindParameter());
		buffer.append(" ");
		buffer.append(parent.getRadioParameter());
		buffer.append(" ");
		buffer.append(parent.getCheckParameter());
		
		String completedFindInfo = buffer.toString();
		
		connection.setMessage(FIND_CMD, completedFindInfo);
	
		String response;
		
		response = connection.buffers[FIND_CMD].read();

	
		if (response.startsWith("200")) {
			MessageViewer.showError(getActionOwner(), "Bad parameter.");
			return;
		}
		
		Vector<Vector> findList = null;
		
		if (response.startsWith("100")) {
			StringTokenizer tokens = new StringTokenizer(response);
			tokens.nextToken();
			tokens.nextToken();
			
			int rowCount = Integer.parseInt(tokens.nextToken());
			
			if (rowCount == 0) {
				JOptionPane.showMessageDialog(parent, "No results found.", "Find Info", JOptionPane.INFORMATION_MESSAGE);
			}
			
			findList = new Vector<Vector>();
			
			for (int i = 0; i < rowCount; i++) {
				response = connection.buffers[FIND_CMD].read();
				findList.add(new Vector<String>(getFindListEntry(response)));
			}
		}

		
		// kreiranje modela podataka
		// TODO voditi racuna o null vrednostima
		
		Vector<Vector> data = new Vector<Vector>();
		
		// FindList
		for (int i = 0; i < findList.size(); i++) {
			String username = findList.get(i).get(0).toString();
			String nickname = findList.get(i).get(1).toString();
			String email = findList.get(i).get(2).toString();
			String ip_address = findList.get(i).get(3).toString();
			String local_address = findList.get(i).get(4).toString();
			String port = findList.get(i).get(5).toString();
			String status = findList.get(i).get(6).toString();
			String regDate = findList.get(i).get(7).toString();
			String avatar = findList.get(i).get(8).toString();
			
			Vector<String> row = new Vector<String>();
			
			row.add(username);
			row.add(nickname);
			row.add(email);
			row.add(ip_address);
			row.add(local_address);
			row.add(port);
			row.add(status);
			row.add(regDate);
			row.add(avatar);
			
			data.add(row);
		}
		
		parent.clearTableModel();
		
		parent.setTableModel(data);
	}
	
	
	
	/**
	 * Metod parsira jedan red find liste, i parsirane podatke smesta u Vector
	 * koji se vraca iz metode.
	 * Ocekivani podaci:
	 * username, nickname, email, ip_address, port, status, reg_date, avatar
	 * @param data - string koji predstavlja jedan red find liste, tj. jednog user-a
	 * @return - parsirani podaci koji predstavljaju user-a u find listi
	 * @author UrosKrkic & Radivoje Popovic
	 */
	private Vector<String> getFindListEntry(String data) {
		Vector<String> entry = new Vector<String>();
		
		StringTokenizer tokens = new StringTokenizer(data);
		
		entry.add(tokens.nextToken());
		entry.add(tokens.nextToken());
		entry.add(tokens.nextToken());
		entry.add(tokens.nextToken());
		entry.add(tokens.nextToken());
		entry.add(tokens.nextToken());
		entry.add(tokens.nextToken());
		entry.add(tokens.nextToken());
		entry.add(tokens.nextToken());
		
		return entry;
	}
	
	
}
